<?php
namespace app\api\controller;
use function GuzzleHttp\Psr7\str;
use think\Controller;
use think\Db;

class  Weixinjinjian extends Base  {
    private $config=array(
        'APPID'              => 'wx0280081f100b9265',
        'MCHID'              => '1603436544',
        'serial_no'              => '399899B61187C62649C28EFA5C6BC7EDFDA1CC88',
        'KEY'                => 'ykIaqVCiOW44kcYfIi6VxflcNlaDKCG5',
        'APPSECRET'          => '93121d5eba0d227aec238cfcd8ae7835',
        'NOTIFY_URL'         => 'http://csdl.jintianjifen.cn/api/Weixin/huidiao',
    );
    public $body;
    public $total_fee;
    public $out_trade_no;

    public function __construct($config=null){
        if (!empty($config)) {
            $this->config=$config;
        }
    }
    protected function apiError($code, $msg = '')
    {
        if (!$msg) {
            $info['msg'] = $this->_error[$code]['msg'];
        } else {
            $info['msg'] = $msg;
        }
        $info['status'] = $code;
        $returnInfo = json_encode($info, JSON_UNESCAPED_UNICODE);
        echo $returnInfo;
        exit();
    }
    /**
     *进件
     */
    public function add(){
        extract(input());
		set_time_limit(0);
        $shop = Db::name('shop')->where('shop_id',$shop_id)
            ->field('shop_id,shop_attestation,shop_status,shop_facade_img,shop_ldentity_img,shop_hand_img,shop_name,shop_contact,shop_sheng_id,shop_city_id,shop_qu_id')
            ->find();
        if($shop['shop_attestation'] != 2||$shop['shop_status'] != 1) return json(['status'=>100,'msg'=>'只有认证通过的商户才可以申请']);
        $data = [
            'sc_shop_id' => $shop_id,
            'business_code' => "shop" . time() . $shop_id,
            'contact_name' => $contact_name,
            'contact_id_number' => $contact_id_number,
            'mobile_phone' => $mobile_phone,
            'contact_email' => $contact_email,

            'license_copy' => $shop['shop_hand_img'],
            'license_number' => $license_number,
            'merchant_name' => $merchant_name,
            'legal_person' => $legal_person,

            'id_card_copy' => $shop['shop_facade_img'],
            'id_card_national' => $shop['shop_ldentity_img'],
            'id_card_name' => $legal_person,
            'id_card_number' => $id_card_number,
            'card_period_begin' => $card_period_begin,
            'card_period_end' => $card_period_end,

            'merchant_shortname' => $shop['shop_name'],
            'service_phone' => $shop['shop_contact'],

            'account_name' => $account_name,
            'account_bank' => $account_bank,
//            'bank_address_code' => $bank_address_code,
//            'bank_name' => $bank_name,
            'account_number' => $account_number,

            'sc_time' => date('Y-m-d H:i:s')
        ];
        if(isset($company_img) && $company_img){
            $data['company_img'] = $company_img;
        }
        if($account_name != $merchant_name) return json(['status'=>100,'msg'=>'开户名称必须与营业执照上“商户名称”一致。']);
        //----------------------------------------------------------------------------------------------------------------
        if($account_bank == '其他银行'){
//            $data['account_bank'] = $account_bank2;
            $data['bank_name'] = $bank_name;
        }
        $zhixia = ['北京','天津','重庆','上海'];
        if(in_array($sheng,$zhixia)) $sheng = '';
        $ssq = '中国,' . $sheng . ',' . $shi . ',' . $qu;
        $ssq2 = '中国,' . $sheng . ',' . $shi;
        $bank_address_code = Db::table('up_zzzzzzz')->where('name',$ssq)->value('code');
        if(!$bank_address_code){
            $bank_address_code = Db::table('up_zzzzzzz')->where('name',$ssq2)->value('code');
        }
        $data['bank_address_code'] = $bank_address_code;
        //----------------------------------------------------------------------------------------------------------------
        $shopCopy = Db::name('shop_copy')->where('sc_shop_id',$shop_id)->find();
        if(!$shopCopy){
            $resId = Db::name('shop_copy')->insertGetId($data);
        }else{
            if($shopCopy['sc_status'] != 1) return json(['status'=>100,'msg'=>'审核中，请勿重复提交~']);
            $resId = Db::name('shop_copy')->where('sc_shop_id',$shop_id)->update($data);
        }
        if(!$resId) return json(['status'=>100,'msg'=>'保存失败，请重新上传~']);
		$img_info = file_get_contents($data['license_copy'] . '?x-oss-process=image/info');
        $img_info = json_decode($img_info,true);
        if($img_info['FileSize']['value'] > 2000000) $data['license_copy'] = $data['license_copy'] . '?x-oss-process=image/quality,Q_50';

        $img_info = file_get_contents($data['id_card_copy'] . '?x-oss-process=image/info');
        $img_info = json_decode($img_info,true);
        if($img_info['FileSize']['value'] > 2000000) $data['id_card_copy'] = $data['id_card_copy'] . '?x-oss-process=image/quality,Q_50';

        $img_info = file_get_contents($data['id_card_national'] . '?x-oss-process=image/info');
        $img_info = json_decode($img_info,true);
        if($img_info['FileSize']['value'] > 2000000) $data['id_card_national'] = $data['id_card_national'] . '?x-oss-process=image/quality,Q_50';

        /*接收请求参数*/
        $param = [
            "business_code" => "shop" . time(),
            "contact_info" => [
                "contact_name" => $contact_name, //管理员姓名
                "contact_id_number" => $contact_id_number, //管理员身份证号
                "mobile_phone" => $mobile_phone,  //管理员电话
                "contact_email" => $contact_email  //管理员邮箱
            ],
            "subject_info" => [
                "subject_type" => "SUBJECT_TYPE_ENTERPRISE",
                "business_license_info" => [
                    "license_copy" => $this->uploadMediaTable($data['license_copy']),  //营业执照
                    "license_number" => $license_number,  //信用代码
                    "merchant_name" => $merchant_name,  //商户名称
                    "legal_person" => $legal_person  //法人
                ],
                "identity_info" => [ //法人信息
                    "id_doc_type" => "IDENTIFICATION_TYPE_IDCARD",
                    "id_card_info" => [
                        "id_card_copy" => $this->uploadMediaTable($data['id_card_copy']),//身份证人像面
                        "id_card_national" => $this->uploadMediaTable($data['id_card_national']),//身份证国徽面
                        "id_card_name" => $legal_person,
                        "id_card_number" => $id_card_number,
                        "card_period_begin" => $card_period_begin,
                        "card_period_end" => $card_period_end
                    ],
                    "owner" => true
                ],
            ],
            "business_info" => [
                "merchant_shortname" => $data['merchant_shortname'], //商户简称
                "service_phone" => $data['service_phone'], //商户客服电话
                "sales_info" => [
                    "sales_scenes_type" => [
                        "SALES_SCENES_MP"
                    ],
                    "mp_info" => [
                        "mp_appid" => "wxcb63bdccb205e77b"
                    ]
                ]
            ],
            "settlement_info" => [
                "settlement_id" => "716",
                "qualification_type" => "零售批发",
//                "activities_id" => "20191030111cff5b5e",
//                "activities_rate" => "0.38",
            ],
            "bank_account_info" => [
                "bank_account_type" => "BANK_ACCOUNT_TYPE_CORPORATE",
                "account_name" => $account_name,
                "account_bank" => $account_bank,
                "bank_address_code" => $bank_address_code,
//                "bank_name" => $bank_name,
                "account_number" => $account_number
            ],
        ];
        //-------------------------------------------------------------------------------------------------------------
        if(isset($company_type) && $company_type){
            if($company_type == 1){
                $param['subject_info']['subject_type'] = 'SUBJECT_TYPE_INDIVIDUAL';
            }
            if($company_id <= 13 || $company_id == 101) $param['settlement_info']['settlement_id'] = '719';
            if($company_id == 14) $param['settlement_info']['settlement_id'] = '720';
            if($company_id == 15) $param['settlement_info']['settlement_id'] = '721';

            if($company_id >= 31 && $company_id <= 51) $param['settlement_info']['settlement_id'] = '716';
            if($company_id == 52) $param['settlement_info']['settlement_id'] = '728';
            if($company_id == 53) $param['settlement_info']['settlement_id'] = '717';
            if($company_id == 201) $param['settlement_info']['settlement_id'] = '716';
            $com_xinxi = $this->getCNmmm();
            $param['settlement_info']['qualification_type'] = $com_xinxi[$company_id];
//            if($company_id < 100){
//                if(!$company_img) return json(['status'=>100,'msg'=>'请上传资质~']);
//                $img_info = file_get_contents($company_img . '?x-oss-process=image/info');
//                $img_info = json_decode($img_info,true);
//                if($img_info['FileSize']['value'] > 2000000) $company_img = $company_img . '?x-oss-process=image/quality,Q_50';
//                $company_imgID = $this->uploadMediaTable($company_img);
//                $param['settlement_info']['qualifications'] = [$company_imgID];
//            }
            if($param['settlement_info']['settlement_id'] == 716 || $param['settlement_info']['settlement_id'] == 719){
                $param['settlement_info']['activities_id'] = "20191030111cff5b5e";
                $param['settlement_info']['activities_rate'] = "0.38";
            }
        }
        if($shop_id == 2){
            return json(['status'=>100,'msg'=>json_encode($param)]);
        }
        //-------------------------------------------------------------------------------------------------------------
        if($account_bank == '其他银行'){
//            $param['bank_account_info']['account_bank'] = $account_bank2;
            $param['bank_account_info']['bank_name'] = $bank_name;
        }
        $param['subject_info']['identity_info']['owner'] = true;
        $param['contact_info']['contact_name'] = $this->getEncryptS($param['contact_info']['contact_name']);
        $param['contact_info']['mobile_phone'] = $this->getEncryptS($param['contact_info']['mobile_phone']);
        $param['contact_info']['contact_email'] = $this->getEncryptS($param['contact_info']['contact_email']);
        $param['contact_info']['contact_id_number'] = $this->getEncryptS($param['contact_info']['contact_id_number']);

        $param['subject_info']['identity_info']['id_card_info']['id_card_name'] = $this->getEncryptS($param['subject_info']['identity_info']['id_card_info']['id_card_name']);
        $param['subject_info']['identity_info']['id_card_info']['id_card_number'] = $this->getEncryptS($param['subject_info']['identity_info']['id_card_info']['id_card_number']);

        $param['bank_account_info']['account_name'] = $this->getEncryptS($param['bank_account_info']['account_name']);
        $param['bank_account_info']['account_number'] = $this->getEncryptS($param['bank_account_info']['account_number']);

        $url = 'https://api.mch.weixin.qq.com/v3/applyment4sub/applyment/' ;
        $merchant_id = $this->config['MCHID']; //服务商商户号
        $serial_no = $this->config['serial_no']; //服务商证书序列号
        $mch_private_key = $this->getPrivateKey(ROOT_PATH.'/public/cert/apiclient_key.pem');
        $timestamp = time();
        $nonce = $this->nonce_str();
        $sign           =$this->signsign($url,'POST',$timestamp,$nonce,json_encode($param),$mch_private_key,$merchant_id,$serial_no);//进行签名操作

        //设置header
        $header         =[//设置发送的头信息
            'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign,//签名
            'Accept:application/json',
            'User-Agent:' . $merchant_id,//服务商的商户号
            'Content-Type:application/json',
            'Wechatpay-Serial:' . $this->getzhengshu()//获取平台证书的序列号，注意：是平台证书，不是上文的商户证书序列号
        ];
        $result=$this->curl($url,json_encode($param),$header);//curl方法见下文
        $result = json_decode($result, true);
        if(isset($result['applyment_id']) && $result['applyment_id']){
            Db::name('shop_copy')->where('sc_shop_id',$shop_id)->update([
                'sc_status' => 2,
                'applyment_id' => $result['applyment_id']
            ]);
            return json(['status'=>200,'msg'=>'提交成功，请等待审核~']);
        }else{
			$remsg = '提交失败';
			if(isset($result['message']) && $result['message']) $remsg = $result['message'];
            return json(['status'=>100,'msg'=>$remsg]);
        }
    }

    public function getCNmmm(){
        $company_sales = [
            1 => '餐饮',
            2 => '食品生鲜',
            3 => '私立/民营医院/诊所',
            4 => '保健器械/医疗器械',
            6 => '互联网售药',
            7 => '线下门店卖药',
            8 => '游艺厅/KTV',
            9 => '网吧',
            10 => '机票/机票代理',
            11 => '宠物医院',
            12 => '学科类培训机构',
            13 => '驾校培训',

            14 => '话费通讯',

            15 => '加油',

            101 => '零售批发/生活娱乐/其他',
            31 => '餐饮',
            32 => '食品生鲜',
            33 => '电信运营商/宽带收费',
            34 => '私立/民营医院/诊所',
            35 => '保健器械/医疗器械',
            37 => '互联网售药',
            38 => '线下门店卖药',
            39 => '游艺厅/KTV',
            40 => '网吧',
            41 => '机票/机票代理',
            42 => '宠物医院',
            43 => '旅行社',
            44 => '宗教组织',
            45 => '房产中介',
            46 => '共享服务',
            47 => '文物经营/文物复制品销售',
            48 => '拍卖',
            49 => '典当',
            50 => '学科类培训机构',
            51 => '驾校培训',

            52 => '话费通讯',

            53 => '加油',

            201 => '零售批发/生活娱乐/其他',
        ];
        return $company_sales;
    }
    /*
    *查询
    */
    public function query()
    {
        $datas = Db::name('shop_copy')->where('sc_status',2)->field('sc_id,applyment_id,error_msg')->select();
        if($datas){
            foreach ($datas as $k => $v){
                $no = $v['applyment_id'];
                $url  = 'https://api.mch.weixin.qq.com/v3/applyment4sub/applyment/applyment_id/'.$no;
                $merchant_id = $this->config['MCHID']; //服务商商户号
                $serial_no = $this->config['serial_no']; //服务商证书序列号
                $mch_private_key = $this->getPrivateKey(ROOT_PATH.'/public/cert/apiclient_key.pem');
                $timestamp =time();
                $nonce  = $this->nonce_str();
                $body="";
                $sign=$this->signsign($url,'GET',$timestamp,$nonce,$body,$mch_private_key,$merchant_id,$serial_no);//签名
                $header = [
                    'Authorization: WECHATPAY2-SHA256-RSA2048 ' .$sign,
                    'Accept: application/json',
                    'User-Agent:' .$merchant_id,
                    'Content-Type :application/json',
                    'Wechatpay-Serial:' .$this->getzhengshu()
                ];
                $result = $this->curl($url,'',$header, 'GET');
                $result = json_decode($result, true);
                if(isset($result['applyment_state']) && $result['applyment_state'] == 'APPLYMENT_STATE_FINISHED'){
                    Db::name('shop_copy')->where('sc_id',$v['sc_id'])->update([
                        'sc_status' => 3,
                        'sc_mch_id' => $result['sub_mchid'],
                        'error_msg' => ''
                    ]);
                }else{
                    if(isset($result['applyment_state_msg']) && $v['error_msg'] != $result['applyment_state_msg']){
                        Db::name('shop_copy')->where('sc_id',$v['sc_id'])->update([
                            'error_msg' => $result['applyment_state_msg']
                        ]);
                    }
                }
            }
        }
        exit();
    }

    /**
     *图片上传
     **/
    public function uploadMedia()
    {
        $file = request()->file('file');
        /*判断必要参数是否存在*/
        if($file){
            $fileInfo = $file->getInfo();
            $url="https://api.mch.weixin.qq.com/v3/merchant/media/upload";//微信的上传地址
            $merchant_id = $this->config['MCHID']; //服务商商户号
            $serial_no = $this->config['serial_no']; //服务商证书序列号
            $mch_private_key = $this->getPrivateKey(ROOT_PATH.'/public/cert/apiclient_key.pem');//读取商户api证书公钥 getPublicKey()获取方法
            $timestamp=time();//时间戳
            $nonce=$this->nonce_str();//随机字符串
            $mime_type=$fileInfo['type'];
            $meta=[
                'filename'=>$fileInfo['name'],
                'sha256'=>hash_file('sha256',$fileInfo['tmp_name'])
            ];
            $sign=$this->signsign($url,'POST',$timestamp,$nonce,json_encode($meta),$mch_private_key,$merchant_id,$serial_no);
            $boundary=uniqid();
            $header=[
                'Content-Type:multipart/form-data;boundary=' . $boundary,
                'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign,
                'Accept:application/json',
                'User-Agent:' . $merchant_id
            ];
            $body='--' . $boundary . "\r\n";
            $body.='Content-Disposition:form-data; name="meta"' . "\r\n";
            $body.='Content-Type:application/json' . "\r\n\r\n";
            $body.=json_encode($meta)."\r\n";
            $body.='--' . $boundary . "\r\n";
            $body.='Content-Disposition:form-data;name="file";filename="' . $meta['filename'] . '"' . "\r\n";
            $body.='Content-Type:' .$mime_type."\r\n\r\n";
            $body.=file_get_contents($fileInfo['tmp_name'])."\r\n";
            $body.='--'.$boundary .'--'."\r\n";
            $result=$this->curl($url,$body,$header);
//                    var_dump($result);die;
            $result=json_decode($result,true);
            return json(['status' => 200, 'msg' => $result['media_id']]);//返回微信返回来的图片标识
        }
        return json(['status' => 100, 'msg' => '']);
    }
    public function uploadMediaTable($imgurl)
    {
        $tmp_name = $imgurl;
        $imgurl = explode('/',$imgurl);
        $nameArr = $imgurl[count($imgurl) - 1];
        $nameArr = explode('.',$nameArr);
        $nameStr = $nameArr[0];
        $fileInfo = [
            'type' => 'image/jpeg',
            'name' => $nameStr . '.jpg',
            'tmp_name' => $tmp_name
        ];

        /*判断请求类型（GET、POST、PUT、DELETE）*/
        $url="https://api.mch.weixin.qq.com/v3/merchant/media/upload";//微信的上传地址
        $merchant_id = $this->config['MCHID']; //服务商商户号
        $serial_no = $this->config['serial_no']; //服务商证书序列号
        $mch_private_key = $this->getPrivateKey(ROOT_PATH.'/public/cert/apiclient_key.pem');//读取商户api证书公钥 getPublicKey()获取方法
        $timestamp=time();//时间戳
        $nonce=$this->nonce_str();//随机字符串
        $mime_type=$fileInfo['type'];
        $meta=[
            'filename'=>$fileInfo['name'],
            'sha256'=>hash_file('sha256',$fileInfo['tmp_name'])
        ];
        $sign=$this->signsign($url,'POST',$timestamp,$nonce,json_encode($meta),$mch_private_key,$merchant_id,$serial_no);
        $boundary=uniqid();
        $header=[
            'Content-Type:multipart/form-data;boundary=' . $boundary,
            'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign,
            'Accept:application/json',
            'User-Agent:' . $merchant_id
        ];
        $body='--' . $boundary . "\r\n";
        $body.='Content-Disposition:form-data; name="meta"' . "\r\n";
        $body.='Content-Type:application/json' . "\r\n\r\n";
        $body.=json_encode($meta)."\r\n";
        $body.='--' . $boundary . "\r\n";
        $body.='Content-Disposition:form-data;name="file";filename="' . $meta['filename'] . '"' . "\r\n";
        $body.='Content-Type:' .$mime_type."\r\n\r\n";
        $body.=file_get_contents($fileInfo['tmp_name'])."\r\n";
        $body.='--'.$boundary .'--'."\r\n";
        $result=$this->curl($url,$body,$header);
        $result=json_decode($result,true);
        return $result['media_id'];//返回微信返回来的图片标识

    }

    /**
     *加密字符串
     */
    private function getEncryptS($str) {
        //$str是要加密的字符串
        $public_key_path = ROOT_PATH.'/public/cert/cert.pem' ; //这是获取证书时存起的平台公钥
        $public_key = file_get_contents($public_key_path);
        $encrypted  = '';
        if (openssl_public_encrypt($str, $encrypted, $public_key, OPENSSL_PKCS1_OAEP_PADDING)){
            //base64
            $sign = base64_encode($encrypted);
        }else{
            throw new \Exception('encrypt failed');
        }
        return $sign;
    }

    /**
     *获取证书
     **/
    public function getzhengshu(){
        $url="https://api.mch.weixin.qq.com/v3/certificates";//获取地址
        $timestamp=time();//时间戳
        $nonce=$this->nonce_str();//获取一个随机字符串
        $body="";
        $mch_private_key = $this->getPrivateKey(ROOT_PATH.'/public/cert/apiclient_key.pem'); //调用获取商户私钥方法传证书文件路径进去
        $merchant_id = $this->config['MCHID']; //服务商商户号
        $serial_no = $this->config['serial_no']; //服务商证书序列号
        $sign=$this->signsign($url,'GET',$timestamp,$nonce,$body,$mch_private_key,$merchant_id,$serial_no);

        $header=[
            'Authorization:WECHATPAY2-SHA256-RSA2048 '.$sign,
            'Accept:application/json',
            'User-Agent:'.$merchant_id
        ];
        $result=$this->curl($url,'',$header,'GET');
        $result=json_decode($result,true);
        $serial_no=$result['data'][0]['serial_no'];//获取的平台证书序列号
        $encrypt_certificate=$result['data'][0]['encrypt_certificate'];
        $sign_key="92rXLzzCg2f3GcjboqqcYb6YuA8q61SW";  //APIv3密钥，商户平台API安全中获取
        $result=$this->decryptToString($encrypt_certificate['associated_data'],$encrypt_certificate['nonce'],$encrypt_certificate['ciphertext'],$sign_key);
        file_put_contents(ROOT_PATH.'/public/cert/cert.pem',$result);//获取的文件临时保存到服务器

        return $serial_no;//返回平台证书序列号
    }

    /**
     *解密方法
     */
    public function decryptToString($associatedData,$nonceStr,$ciphertext,$aesKey){
        $ciphertext=\base64_decode($ciphertext);
        if(function_exists('\sodium_crypto_aead_aes256gcm_is_available')&& \sodium_crypto_aead_aes256gcm_is_available()){
            return \sodium_crypto_aead_aes256gcm_decrypt($ciphertext,$associatedData,$nonceStr,$aesKey);
        }
        if (function_exists('\Sodium\crypto_aead_aes256gcm_is_available') &&
            \Sodium\crypto_aead_aes256gcm_is_available()) {
            return \Sodium\crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, $aesKey);
        }
        if(PHP_VERSION_ID >= 70100 && in_array('aes-256-gcm', \openssl_get_cipher_methods())){
            $ctext=substr($ciphertext,0,-16);
            $authTag=substr($ciphertext,-16);
            return \openssl_decrypt(
                $ctext,
                'aes-256-gcm',
                $aesKey,
                \OPENSSL_RAW_DATA,
                $nonceStr,
                $authTag,
                $associatedData
            );
        }
        throw new \RuntimeException('php7.1');
    }

    /**
     *curl请求方法
     **/
    public function curl($url,$data=[],$header,$method='POST'){
        $curl=curl_init();
        curl_setopt($curl,CURLOPT_URL,$url);
        curl_setopt($curl,CURLOPT_HTTPHEADER,$header);
        curl_setopt($curl,CURLOPT_HEADER,false);
        curl_setopt($curl,CURLOPT_RETURNTRANSFER,1);
        curl_setopt($curl,CURLOPT_SSL_VERIFYPEER,false);
        if($method=="POST"){
            curl_setopt($curl,CURLOPT_POST,TRUE);
            curl_setopt($curl,CURLOPT_POSTFIELDS,$data);
        }
        $result=curl_exec($curl);
        curl_close($curl);
        return $result;
    }

    /**
     *生成一个随机字符串
     */
    private function nonce_str()
    {
        return date('YmdHis', time()) . rand(18080,99999);
    }

    /**
     *获取商户私钥
     */
    public static function getPrivateKey($path)
    {
        return openssl_get_privatekey(file_get_contents($path));
    }

    public function signsign($url,$http_method,$timestamp,$nonce,$body,$mch_private_key,$merchant_id,$serial_no){
        $url_parts=parse_url($url);
        $canonical_url=($url_parts['path'].(!empty($url_parts['query'])?"?${url_parts['query']}":""));
        $message=
            $http_method . "\n".
            $canonical_url . "\n".
            $timestamp . "\n".
            $nonce . "\n".
            $body . "\n";
        openssl_sign($message,$raw_sign,$mch_private_key,'sha256WithRSAEncryption');
        $sign=base64_encode($raw_sign);
        $schema='WECHATPAY2-SHA256-RSA2048';
        $token=sprintf(
            'mchid="%s",nonce_str="%s",signature="%s",timestamp="%d",serial_no="%s"',
            $merchant_id,
            $nonce,
            $sign,
            $timestamp,
            $serial_no
        );
        return $token;
    }
}